package devent.phase1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;

import android.os.Environment;
import android.util.Log;

public class ZipGenerate extends Plugin {

	private String zipFile = "";// /mnt/sdcard/csdphotos.zip
	private String zipRootDirPath = "";// /mnt/sdcard/csdphotos
	private String zipRootDir = "";// csdphotos

	/**
	 * Executes the request and returns PluginResult.
	 * 
	 * @param action
	 *            The action to execute.
	 * @param args
	 *            JSONArry of arguments for the plugin.
	 * @param callbackId
	 *            The callback id used when calling back into JavaScript.
	 * @return A PluginResult object with a status and message.
	 */
	public PluginResult execute(String action, JSONArray args, String callbackId) {
		if (args.length() == 0) {
			Log.e("ZipGenerate",
					"Error: parameters array cannot be null, it must contain atleast one value");
			return new PluginResult(PluginResult.Status.ERROR);
		}

		if (checkParamsNull(args) == true) {
			Log.e("ZipGenerate",
					"Error: parameters array cannot contain null values");
			return new PluginResult(PluginResult.Status.ERROR);
		}

		try {
			String sdDir = Environment.getExternalStorageDirectory().toString()
					+ "/";
			zipRootDirPath = sdDir + "iControl/";
			zipFile = sdDir + "iControl_upload/" + args.getString(0);
			zipRootDir = zipRootDirPath.substring(zipRootDirPath
					.lastIndexOf('/') + 1);
			Log.i("ZipGenerate", "ZipFile: " + zipFile);
			Log.i("ZipGenerate", "zipRootDirPath: " + zipRootDirPath);
			Log.i("ZipGenerate", "zipRootDir: " + zipRootDir);

			execGenerateZip();
			return new PluginResult(PluginResult.Status.OK, "OK");
		} catch (Exception e) {
			Log.e("ZipGenerate", "Error: exception " + e.toString());
		}
		return new PluginResult(PluginResult.Status.ERROR);
	}

	private boolean checkParamsNull(JSONArray args) {
		for (int i = 0; i < args.length(); i++)
			if (args.isNull(i) == true)
				return true;

		return false;
	}

	private void execGenerateZip() throws Exception {
		ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
		Log.i("ZipGenerate", "Created zip file: " + zipFile);
		generateZip(zipRootDirPath, zos);
		Log.i("ZipGenerate", "Closing zip file: " + zipFile);
		zos.close();
	}

	private void generateZip(String zipDirPath, ZipOutputStream zos)
			throws Exception {
		File zf = new File(zipDirPath);
		String[] dirList = zf.list();
		FileInputStream fis;
		ZipEntry ze;
		File f;
		byte[] readBuffer = new byte[2048];
		int bytesRead = 0;
		String absoluteFilePath;

		for (int i = 0; i < dirList.length; i++) {
			f = new File(zf, dirList[i]);
			absoluteFilePath = f.getPath();

			if (f.isDirectory()) {
				generateZip(absoluteFilePath, zos);
				continue;// @note: when the recursive call returns, we know that
							// "f" is a directory, so *DONT* proceed further
			}

			Log.i("ZipGenerate", "Adding file to zip: " + f.getName());

			fis = new FileInputStream(f);

			// @note: we need to extract the entire subfolder(s) path leading
			// upto the file being zipped currently
			// starting from the zipRootDir, which we then put into relativePath
			String relativePath = absoluteFilePath.substring(absoluteFilePath
					.indexOf(zipRootDir));
			String relativePath2 = dirList[i].substring(dirList[i]
					.lastIndexOf("/") + 1);
			Log.i("ZipGenerate", "Zip Entry Path: " + relativePath);
			Log.i("ZipGenerate", "Zip Entry Path: " + relativePath2);

			ze = new ZipEntry(relativePath2);

			zos.putNextEntry(ze);
			while ((bytesRead = fis.read(readBuffer)) != -1)
				zos.write(readBuffer, 0, bytesRead);

			fis.close();
			Log.i("ZipGenerate", "Added file to zip: " + f.getName());
		}
	}

}
